/**
 * @file client_perf.hpp
 * Performance counter set helper for Gestalt client
 */

#pragma once

#include <vector>
#include <chrono>
#include <filesystem>
#include <fstream>

#include "./duration_recorder.hpp"


namespace gestalt {
namespace perf {

using namespace std;


/**
 * @note __NOT__ thread-safe
 */
struct ClientLatencyRecorder {
    using duration_resolution = std::chrono::microseconds;
    using recorder_type = BasicDurationRecorder<duration_resolution>;
    recorder_type read_rec, write_rec;

public:
    ClientLatencyRecorder()
    { }

public:
    enum class op_type { read, write };

    template <op_type op>
    inline void tick()
    {
        if constexpr (op == op_type::read) {
            read_rec.tick();
        }
        else if constexpr (op == op_type::write) {
            write_rec.tick();
        }
    }
    inline void read_tick()
    {
        tick<op_type::read>();
    }
    inline void write_tick()
    {
        tick<op_type::write>();
    }

    template <op_type op>
    inline void tock()
    {
        if constexpr (op == op_type::read) {
            read_rec.tock();
        }
        else if constexpr (op == op_type::write) {
            write_rec.tock();
        }
    }
    inline void read_tock()
    {
        tock<op_type::read>();
    }
    inline void write_tock()
    {
        tock<op_type::write>();
    }

public:
    void dump(const filesystem::path &read_out,
        const filesystem::path &write_out) const
    {
        read_rec.dump(read_out);
        write_rec.dump(write_out);
    }
};  /* class ClientLatencyRecorder */

}   /* namespace perf */
}   /* namespace gestalt */
